package com.dfs.parent.order.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.fastjson2.JSON;
import com.dfs.parent.common.core.domain.Result;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/order")
@RequiredArgsConstructor
public class OrderSentinelController {

    /**
     * <h2>初始化流控规则</h2>
     * 初始化顺序问题
     * @PostConstruct 的 init() 方法会在 Spring 容器初始化阶段执行，但此时 Sentinel 的 Transport 模块（负责连接 Dashboard）可能还未完全初始化。
     *
     * 如果手动加载规则 早于 Transport Server 启动，会导致 Sentinel 客户端未注册到 Dashboard。
     *
     * 规则加载方式冲突
     * 通过 FlowRuleManager.loadRules() 硬编码加载规则 会覆盖 Sentinel 的默认初始化流程，可能中断与 Dashboard 的通信。
     * */
//    @PostConstruct
//    public void init() {
//
//        // 流控规则集合
//        List<FlowRule> flowRules = new ArrayList<>();
//        // 创建流控规则
//        FlowRule flowRule = new FlowRule();
//        // 设置流控规则 QPS, 限流阈值类型 (QPS, 并发线程数)
//        flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
//        // 流量控制手段
//        flowRule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);
//        // 设置受保护的资源
//        flowRule.setResource("flowRuleCodehh");
//        // 设置受保护的资源的阈值
//        flowRule.setCount(1);
//        flowRules.add(flowRule);
//
//        // 加载配置好的规则
//        FlowRuleManager.loadRules(flowRules);
//    }

    /**
     * 全局统一BlockException
     * @return
     */
    @GetMapping("/flow-rule")
   // @SentinelResource(value = "flowRuleCodehh",blockHandler = "handleException")
  //  @SentinelResource(value = "flowRuleCodehh",blockHandler = "handleException",fallback ="fallback" )
    @SentinelResource(value = "flowRuleCodehh")
    public Result<String> flowRuleCode() {
        log.info("request flowRuleCode");
     //   int a = 10/0;
        return  Result.ok( "imooc-qinyi-ecommerce");
    }

    @GetMapping("/test-rule")
    public Result<String> testFlowRule() {
    //    int a = 10/0;
        log.info("request testFlowRule=========");
        return  Result.ok( "test-rule");
    }
    @GetMapping("/test1-rule")
    public Result<String> test1FlowRule() {
        log.info("request testFlowRule1111=========");
        return  Result.ok( "test1111-rule");
    }
    @GetMapping("/test-resource-rule")
     @SentinelResource(value = "testResourceFlowRule")
    public Result<String> testResourceFlowRule() {
        log.info("request testResourceFlowRule=========");
        return  Result.ok( "test-resource-rule");
    }
    /**
     * <h2>当限流异常抛出时, 指定调用的方法</h2>
     * 是一个兜底策略
     * */
    public Result<String> handleException(BlockException exception) {
        log.error("has block exception: [{}]", JSON.toJSONString(exception.getRule()));
        return  Result.fail("flow rule exception1111");
    }

    public Result<String> fallback() {
        return  Result.fail("flow rule fallback22222");
    }
}
